前一章已經確認哪些資料需要遷移、封存、保留查詢或刪除。接下來需要將核准遷移的資料放入目標資料庫,並且保留資料含義、關係與必要的歷史內容。
資料出現在目標資料庫,不代表遷移已經完成。目標系統必須能正確解讀資料,主鍵與外部鍵關係不能中斷,日期、數值及空值也要符合目標規則。遷移程序還需要能重複演練、記錄錯誤,並且在正式切換前處理遷移期間產生的異動。
遷移方法可以先按照資料庫產品與版本分成三類,再根據資料量、可停止寫入的時間及轉換需求選擇實際工具。
本文按照來源與目標使用的資料庫產品分類。「相同資料庫產品」 是指產品名稱相同,例如 MySQL → MySQL、PostgreSQL → PostgreSQL。「不同資料庫產品」 則是產品名稱不同,例如 MySQL → PostgreSQL。
版本是否相同需要另外判斷。即使產品與版本相同,兩邊也不一定能直接交換所有內容,還需要確認字元集、文字定序(Collation)、時區、擴充項目及執行設定。版本升級時,則要以原廠列出的相容範圍與升級路徑為準。
| 分類 | 優先考慮的方法 | 主要判斷條件 |
|---|---|---|
| 相同資料庫產品、相同版本 | 原生完整備份與復原。需要縮短停止寫入時間時,搭配原生複寫或異動資料擷取(Change Data Capture, CDC) | 來源與目標版本及設定相容,資料結構沒有大幅調整 |
| 相同資料庫產品、升級版本 | 相容的備份與復原、原生邏輯匯出與匯入,或原廠升級工具 | 原廠支援直接升級或指定的中繼版本,並且已確認跨版本相容性 |
| 不同資料庫產品 | 擷取、轉換與載入(Extract, Transform, Load, ETL)工具、資料庫轉換工具、或自訂遷移程式 | 來源與目標的型別、結構、限制條件或查詢行為不同,需要明確轉換 |
這項分類只決定優先評估的方法。即使資料庫產品與版本相同,如果目標系統已重新設計資料模型,仍可能需要使用邏輯匯出、ETL 或自訂程式轉換資料。
選擇工具前,需要先記錄來源與目標的差異,避免執行到一半才發現資料無法解讀。至少要確認下列內容:
來源與目標結構不同時,可以使用資料對應表保存轉換規則:
| 項目 | 需要記錄的內容 |
|---|---|
| 來源 | 資料表、欄位、型別、允許值及資料含義 |
| 目標 | 目標資料表、欄位、型別、限制條件及預設值 |
| 轉換 | 格式轉換、代碼對照、計算方式、合併或拆分規則 |
| 關係 | 主鍵、外部鍵、新舊識別碼及相依資料的處理順序 |
| 例外 | 缺漏、重複、無效或無法轉換資料的處理方式 |
| 驗證 | 預期筆數、關聯、彙總結果、抽樣條件及功能規則 |
資料對應表需要和遷移程式一起管理。規則改變時,兩者都要更新,否則文件與實際結果就會逐漸不一致。
來源與目標使用相同資料庫產品及版本,而且目標資料結構沒有明顯改變時,可以優先使用資料庫原生的完整備份與復原。這類工具通常能同時處理資料、型別、限制條件、索引及其他資料庫物件,減少逐項重建的工作。
可以停止來源寫入時,流程相對單純:
需要縮短停止寫入時間時,可以先建立完整副本,再使用原生複寫或 CDC 持續同步新增與異動的資料。正式切換時只需要停止寫入、完成最後一次同步並驗證差異。這種方式需要額外確認同步範圍,因為資料庫物件變更、識別碼目前值或部分設定未必會跟著資料異動一起複寫。
完整備份也未必包含資料庫以外的設定、檔案或相依內容。遷移清單需要分別標示備份會處理哪些項目,以及哪些項目要用其他方式建立。
版本升級會增加格式與行為不相容的風險。執行前需要先確認來源版本能否直接升級至目標版本,或必須先經過原廠指定的中繼版本。正式遷移應該保留來源資料庫,先在獨立目標資料庫完成升級與驗證。
可以按照相容條件選擇下列方法:
邏輯匯出與匯入通常比完整備份更容易跨版本處理,但需要確認型別、語法、預設值、文字定序、識別碼產生規則與擴充項目是否仍具有相同行為。資料庫引擎升級與目標系統的資料模型調整也要分開處理,避免把兩種變更混在同一個無法定位錯誤的步驟中。
每一條升級路徑都需要先演練。演練結果要記錄執行時間、警告、失敗項目、修正方式及驗證結果,才能判斷正式切換需要保留多少時間。
來源與目標使用不同資料庫產品時,欄位名稱相同也不代表資料可以直接轉移。數值精度、日期範圍、布林值、空值、文字長度、大小寫比較與自動產生識別碼的方式都可能不同。遷移前需要先完成結構與欄位對應,再選擇能實作這些規則的方法。
下列方法可以分別使用,也可以依資料特性搭配:
擷取、轉換與載入(Extract, Transform, Load, ETL)工具可以將資料遷移拆成三個可獨立檢查的階段:
ETL 工具可以集中管理資料連線、轉換步驟、執行順序與錯誤分流,但不能自行判斷欄位含義或正確的功能規則。資料對應表仍是轉換依據,工具中的每一項欄位對應、預設值與例外處理都要能回到已確認的規則。
為了讓流程可以演練及重新執行,ETL 工作至少要具備下列設計:
如果來源在完整載入期間仍會異動,還要確認工具是否支援增量擷取或異動資料擷取(Change Data Capture, CDC)。有些工具適合執行完整 ETL,但不負責持續擷取資料庫異動。這種情況需要搭配資料庫原生複寫、CDC 工具或可驗證的異動時間欄位。新增、修改與刪除都要分別測試,不能只確認新增資料。
選擇 ETL 工具時,需要比較下列條件:
下列工具可以作為評估起點。選定前仍要用具代表性的資料進行概念驗證(Proof of Concept, POC),確認連接器、型別轉換、處理量與錯誤復原方式符合實際需求。
| 工具 | 工具特色 | 適合情況 | 使用時要確認 |
|---|---|---|---|
| Apache Hop | 以視覺化管線讀取、轉換及寫入資料,並以工作流程安排多個管線、前置步驟及錯誤處理。 | 適合需要連接、查找、過濾、欄位轉換及多步驟協調的完整 ETL 流程。 | 確認資料庫外掛程式、驅動程式與版本相容,並且另外設計批次進度、重跑及驗證紀錄。 |
| Apache SeaTunnel | 以來源、轉換、目標組成資料管線,JDBC 連接器可以批次或持續讀寫多種資料庫。 | 適合資料量較大、多資料表,或同時需要完整載入與增量流程的遷移。 | 確認來源與目標連接器的功能差異、JDBC 驅動程式版本,以及需要的 CDC 與交易行為是否受支援。 |
| Apache NiFi | 提供視覺化資料流、背壓控制(Back Pressure Control)、資料溯源(Data Provenance)及重播能力。 | 適合持續搬移、路由不同來源,以及需要追查資料經過哪些步驟的流程。 | 複雜的關聯式結構轉換可能需要額外流程元件或查詢,並且要另外確認資料庫交易界線與目標限制條件。 |
| Airbyte | 以連接器執行完整或增量資料複寫,部分資料庫連接器支援 CDC。 | 適合來源與目標已有可用連接器,而且主要需求是資料搬移與同步的情況。 | Airbyte 的定位偏向擷取、載入與轉換(Extract, Load, Transform, ELT)及資料複寫。需要逐一確認同步模式、刪除處理與目標資料結構。複雜轉換可能要在載入後或其他流程完成。 |
工具名稱相同也可能因版本、連接器及執行方式而具有不同功能。正式採用前,需要使用實際來源與目標版本完成完整載入、失敗重跑、增量同步及資料驗證,不能只按照功能清單決定。
CSV 只保存欄位順序與文字內容,不會保存欄位型別、主鍵、外部鍵、索引及資料庫限制。使用前需要固定下列規則:
二進位資料、大型物件及複雜巢狀結構通常不適合直接放入 CSV。可以改用轉換工具或自訂程式處理內容,並在資料表中保存能重建關係的識別資訊。大量資料也需要分批匯出及匯入,避免單次工作占用過多執行資源或長時間鎖定資料庫。
CSV 與其他中介檔案可能包含個人資料或敏感資訊。遷移流程需要限制存取、加密保存、記錄用途,並且在演練或正式遷移結束後按照既定期限清除。
物件關聯對映(Object-Relational Mapping, ORM)工具常把「遷移」用於兩種不同工作,使用前需要先區分目的。
第一種是結構遷移。ORM 以版本化腳本建立或調整目標資料庫的資料表、欄位、索引及限制條件,適合管理目標系統的資料模型變更。這項功能不會自動搬移來源資料,也不能取代資料庫引擎的版本升級程序。
第二種是使用 ORM 撰寫自訂資料遷移程式。程式分別連接來源與目標資料庫,讀取來源模型、套用轉換規則,再將結果寫入目標模型。這種方式適合不同資料庫產品,或來源與目標資料模型差異較大的情況。
ORM 工具通常與特定程式語言或框架整合。選擇時要先確認目標系統採用的技術、資料庫支援範圍及遷移工作是否需要獨立執行,不需要只為了搬移資料而引入另一套程式語言或框架。
| 工具 | 工具特色 | 適合情況 | 使用時要確認 |
|---|---|---|---|
| Entity Framework Core(EF Core) | 將 .NET 資料模型與資料庫欄位對映,遷移(Migrations)功能可以比較模型版本、產生結構遷移檔案,並記錄已套用的遷移。 | 適合目標系統使用 .NET,而且希望用同一套模型管理目標結構及撰寫資料轉換程式的情況。 | 自動產生的結構異動需要人工檢查及演練。正式遷移不宜只在程式啟動時直接套用。大量資料仍要分批處理或搭配原生批次功能。 |
| Django ORM | 內建結構遷移機制,也能使用 RunPython 撰寫與模型版本一起執行的資料遷移。 |
適合目標系統使用 Django,而且資料調整與該系統的模型版本密切相關的情況。 | 資料遷移需要自行撰寫,並使用遷移當時的歷史模型。需要復原時要另外定義反向處理。大量資料要避免逐筆儲存。 |
| TypeORM | 提供 JavaScript 與 TypeScript 的物件對映、查詢及交易控制,也能比較實體定義與既有資料庫結構,產生及執行版本化遷移檔案。 | 適合目標系統使用 JavaScript 或 TypeScript,而且希望以單一工具管理實體、查詢、交易及資料庫結構異動的情況。 | 使用遷移機制時要關閉自動結構同步。自動產生的 SQL 仍需人工檢查,資料轉換要在遷移檔案中明確撰寫。大量資料應該分批處理,並且演練復原方式。 |
| Prisma ORM | 提供 Node.js 與 TypeScript 的型別安全資料存取。Prisma Migrate 可以依 Prisma 結構描述產生可調整的 SQL 遷移檔案,並保存遷移歷程。 | 適合目標系統使用 Node.js 或 TypeScript,而且希望以同一份結構描述管理資料存取與資料庫結構異動的情況。 | 既有資料庫導入時,要先反向解析(Introspection)並建立基準(Baseline)。產生的 SQL 仍需人工檢查。大量資料搬移及複雜轉換要另寫程式並分批處理。Prisma Migrate 不適用於 MongoDB。 |
這些工具都能協助建立目標結構或撰寫資料轉換程式,但不會自動產生正確的欄位對應與功能規則。採用前仍要使用實際來源與目標版本驗證型別支援、產生的結構異動、批次效能及錯誤復原方式。
ORM 資料遷移程式需要明確處理下列工作:
ORM 逐筆建立物件及追蹤狀態可能產生額外負擔。資料量較大時,需要實際測量批次大小與執行時間,並且視需要搭配 ORM 的批次功能或資料庫原生批次匯入。複雜型別、資料庫特有功能或大量直接複製通常更適合原生工具,不需要為了統一程式寫法而全部改用 ORM。
正式遷移前通常會執行多次演練。程序如果只能從頭執行,單一錯誤就可能浪費大量時間。如果重跑會產生重複資料,又無法安全修正問題。因此,每次遷移都需要有可追蹤的執行紀錄。
每個批次至少記錄遷移版本、來源範圍、開始與結束時間、讀取筆數、寫入筆數、略過筆數、錯誤筆數及完成狀態。程式與轉換規則也要保存版本,讓結果可以對應到實際使用的內容。
重新執行可以採用下列方式:
遷移程式不應該直接修改來源資料來掩蓋問題。需要清理或補正的內容,應該記錄原始值、轉換結果及核准的處理方式,讓演練與正式遷移使用相同規則。
只比較資料總筆數,可能看不出關聯錯置、數值截斷或代碼轉換錯誤。驗證需要從結構、數量、關係、內容與功能規則逐層進行。
| 驗證層次 | 檢查內容 |
|---|---|
| 結構 | 目標資料表、欄位、型別、限制條件、索引及識別碼產生方式符合目標設計 |
| 數量 | 各資料表及重要分類的來源筆數、成功筆數、略過筆數與錯誤筆數可以互相對應 |
| 關係 | 主鍵沒有重複,必要外部鍵都有對應目標,沒有遺失相依資料 |
| 內容 | 日期、時區、空值、文字、代碼及數值精度符合轉換規則 |
| 彙總 | 重要數量、金額或其他可計算結果在允許差異範圍內一致 |
| 功能規則 | 目標系統可以用遷移資料完成必要的查詢、計算與狀態變更 |
抽樣資料需要涵蓋一般內容、邊界值、空值、特殊字元、較早資料及曾經轉換失敗的類型。每一項差異都要能分類為核准的轉換結果、來源資料問題或遷移錯誤。無法說明的差異不能直接列為通過。
驗證結果應該和遷移執行紀錄保存於同一次演練中。下一次執行才能比較錯誤是否已修正、時間是否符合切換安排,以及是否出現新的差異。
如果完整遷移期間來源資料仍會異動,只建立一次資料快照就會遺漏後續內容。遷移流程需要定義一個一致的來源時間點,並且記錄該時間點之後新增、修改與刪除的資料。
常見切換流程如下:
復原方案需要區分目標資料庫是否已經接受新寫入。尚未產生新資料時,可以停止目標系統並切換回既有系統。目標資料庫已經產生新資料時,則要先停止寫入,按照預先確認的方式保存、反向同步或處理這些異動,再決定是否切換回既有系統。直接切回來源資料庫可能遺失切換後的內容。
正式切換前,至少要完成一次包含完整遷移、增量同步、驗證、切換與復原的演練。只有各階段的負責人、執行時間、停止條件及結果都能確認,遷移流程才具備實際執行的基礎。